<!--
 * @Descripttion: 
 * @Author: yuxi
 * @Date: 2022-09-15 14:58:04
 * @LastEditors: yuxi
<<<<<<< HEAD
 * @LastEditTime: 2023-07-16 20:52:56
=======
 * @LastEditTime: 2023-07-18 15:00:09
>>>>>>> 8794988e9da3725f6f1a88fd948a6554f245837e
-->
<template>
  <div class="map-container">
    <MiningMap :center="center" :zoom="zoom" :useContextMenu="true" :log="true" @pointermove="handleClick" @ready="handleReady">
      <MiningTiandituLayer
        layerName="基础底图"
        :ak="key"
        @ready="ready"
        layerType="img_w"
      ></MiningTiandituLayer>
      <MiningVectorLayer
        v-for="layer in layers"
        :log="true"
        :featureStyle="style"
        :key="layer.layerId"
        :layerName="layer.layerName"
        :layerId="layer.layerId"
        :needModify="true"
        ref="vlayer"
        :properties="layer"
        @ready="reloadLayerControl"
        @drawEnd="
          (feature) => {
            drawEnd(layer, feature);
          }
        "
      >
        <MiningLineString
          v-for="feature in groupFeatures[layer.layerId]"
          :key="feature.get('properties').id"
          :feature="feature"
          :canModifyGeom="editLayer && editLayer.layerId === layer.layerId"
          :canRemove="editLayer && editLayer.layerId === layer.layerId"
          @remove="handleRemove"
          @updated="handleLineUpdated"
        ></MiningLineString>
      </MiningVectorLayer>

      <MiningLayerControl ref="layerControl">
        <template #layer="{ layer, layer_index, properties }">
          <MiningLayerControlItem :layer="layer">
            <template #addon>
              <div>
                <!-- <i class="el-icon-edit"></i> -->
                <i
                  v-if="layer_index > 0 && !properties.isLock"
                  class="el-icon-lock"
                  @click="unlock(layer)"
                  style="margin-right: 5px"
                ></i>
                <i
                  v-if="layer_index > 0 && properties.isLock"
                  class="el-icon-unlock"
                  @click="lock(layer)"
                  style="margin-right: 5px"
                ></i>
                <i
                  v-if="layer_index > 0 && properties.isLock"
                  class="el-icon-plus"
                  @click="startEdit(layer)"
                  style="margin-right: 5px"
                ></i>
                <i
                  v-if="layer_index > 0"
                  class="el-icon-delete"
                  @click="removeLayer(layer)"
                ></i>
              </div>
            </template>
          </MiningLayerControlItem>
        </template>
        <template #extend>
          <div class="add-btn">
            <el-button size="small" @click="handleAddLayer">添加图层</el-button>
          </div>
        </template>
      </MiningLayerControl>

      <MiningStyleControl
        v-if="editStyle"
        :defaultStyle="editStyle"
        @submit="endEditStyle"
      ></MiningStyleControl>
    </MiningMap>
  </div>
</template>

<script>
import MiningMap from 'mining-map/Map'
import MiningTiandituLayer from 'mining-map/Layers/TiandituLayer'
import { TiandituKey } from '@/config/config.js';
import {Circle as CircleStyle, Fill, Stroke, Style, Stroke as StrokeStyle, Fill as FillStyle,Icon} from 'ol/style';
import {Vector as VectorSource} from 'ol/source';
import {  Vector as VectorLayer} from 'ol/layer';
import MiningLayerControl from 'mining-map/Control/LayerControl';
import MiningLayerControlItem from 'mining-map/Control/LayerControlItem';
import MiningVectorLayer from 'mining-map/Layers/VectorLayer'
import MiningLineString from 'mining-map/Features/LineString';
import MiningStyleControl from 'mining-map/Control/StyleControl';
import { MiningStyle } from 'mining-map/Style';

import marker from '@/assets/images/marker.png'
import {findAndCountAll, createOne, deleteOne, updateOne} from '@/apis/attr'

import {createOne as createGeo, findAndCountAll as findAllGeos, updateOne as updateGeo, deleteOne as deleteGeo } from '@/apis/geo'

import GeoJSON from 'ol/format/GeoJSON';
import Feature from 'ol/Feature'; 
 

import Select from 'ol/interaction/Select.js';
import {altKeyOnly, click, pointerMove} from 'ol/events/condition.js';

 
export default {
  name: 'LineManager',
  title: '线路图层',
  parentTitle: '业务组件',
  components: {
    MiningMap,
    MiningTiandituLayer,
    MiningLayerControl,
    MiningLayerControlItem,
    MiningVectorLayer,
    MiningLineString,
    MiningStyleControl
    // MiningPoint
  },
  data () {
    const style = new Style({
      stroke: new StrokeStyle({
        color: 'blue',
        lineDash: [10],
        width: 3,
      }),
      fill: new FillStyle({
        color: 'rgba(0, 0, 255, 0.1)',
      }),
      image: new Icon({
        anchor: [0.5, 46],
        anchorXUnits: 'fraction',
        anchorYUnits: 'pixels',
        src: marker,
      })
    })
    return {
      center: [116.43396401346438,39.926523711148874],
      zoom: 17,
      key: TiandituKey,
      draw: null,
      snap: null,
      select: null,
      modify: null,
      layers: [],
      style,
      map: null,
      features: [],
      activeFeature: null,
      editing: false,
      editStyle: null,
      styleEditing: true,
    }
  },
  created() {
  },
  computed:{
    editLayer () {
      return this.layers.find(l => {
        return l.isLock
      })
    },
    groupFeatures () {
      let groups = {}
      this.features.map(f => {
        let properties = f.get('properties')
        groups[properties.layer_id]= groups[properties.layer_id] || []
        groups[properties.layer_id].push(f)
      })
       
      return groups
    }, 
  },
  watch: {
    editLayer () {
       
    },
    groupFeatures () {
      console.log('groupFeatures', this.groupFeatures)
    }
  },
  methods: {
    ready ({ map }) {
      this.map = map
      this.map.on('contextmenu', (e)  => {
        console.log(e)
      })

      this.fetchLayers()
    }, 
    // 查询服务器图层
    fetchLayers () {
      findAndCountAll({
        table: 'layer_info',
        page:1,
        pageSize: 100
      }).then(res => { 
        if(res.code === 0) {
          this.layers = res.data.rows.filter(r => {
            return !r.geom
          })
          .map(r => {
            return {
              layerId: r.id,
              layerName: r.name,
              type: 'vectorLayer',
              isLock: r.isLock
            }
          })
          this.findAllGeos()
          this.$nextTick(() => {
            this.reloadLayerControl()
          })
        }
      })
    },
    // 查询所有要素
    findAllGeos () {
      findAllGeos({
        table: 'line',
        page:1,
        pageSize: 100
      }).then(res => { 
        if(res.code === 0) {
          this.features = res.data.rows.map(r => { 
            let style = null
            // 处理样式
            if(r.style) {
              style = new MiningStyle()
              style.fromJSON(JSON.parse(r.style))
            } 
            let f= new Feature({
              type: 'LineString',
              geometry: new GeoJSON().readGeometry(r.geom),
              name: r.id,
              style: style || undefined,
              properties: {
                id: r.id,
                layer_id: r.layer_id,
                style: r.style
              }
            })
            if(style) {
              f.setStyle(style)
            }
            return f
          })
        }
      })
      
    },
    // 绘制结束
    drawEnd(layer, feature) {
      const featureGeoJSON = new GeoJSON().writeFeatureObject(feature) 
      createGeo({
        table: 'line',
        geom: featureGeoJSON.geometry,
        layer_id: layer.layerId
      }).then(res  => {
        if(res.code === 0) {
          let {data} = res
          let newfeature = new Feature({
              type: 'LineString',
              geometry: new GeoJSON().readGeometry(data.geom),
              name: data.id,
              properties: {
                id: data.id,
                layer_id: data.layer_id
              }
          })
          this.features.push(newfeature)  
        }
      }).finally(() => {
        // source.refresh()
      })
    },  
    // 添加图层 
    handleAddLayer () { 
      let layerName = '图层' + (this.layers.length)
      createOne({
        table: 'layer_info',
        name:  layerName,
        order: this.layers.length
      }).then(() => {
        this.fetchLayers()
        this.$message.success(`${layerName}添加成功`);
      })
    },
    // 刷新图层控件
    reloadLayerControl () {
      this.$refs.layerControl.load() 
    },
    // 删除图层
    removeLayer (layer) {
      console.log(layer.get('layerId'))
      let layerId = layer.get('layerId')
      let layerName = layer.get('layerName')
      this.$confirm('是否确认删除当前图层?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          deleteOne({
            table: 'layer_info',
            id: layerId
          }).then(res => {
            if(res.code === 0) {
              this.fetchLayers()
              this.$message.success(`${layerName}删除成功`);
            }
          })
        })
    },
    // 解锁图层
    unlock (layer) {
      if(!layer) {
        layer = this.activeFeature.layer
      }
      let layerId = layer.get('layerId')
      let layerName = layer.get('layerName')
      this.$message(`图层${layerName}解锁`);
      this.editing = true
      updateOne(
        {
          table: 'layer_info',
          id: layerId,
          isLock: true
        }
      ).then(() => {
        this.fetchLayers()
      })
    },
    // 锁定图层
    lock (layer) {
      let layerId = layer.get('layerId')
      let layerName = layer.get('layerName')
      this.$message(`图层${layerName}锁定！`);
      this.stopEdit(layer)

      updateOne(
        {
          table: 'layer_info',
          id: layerId,
          isLock: false
        }
      ).then(() => {
        this.fetchLayers()
      })
      this.editing = false
    },
    // 开启编辑
    startEdit (layer) {
      if(!layer) {
        layer = this.activeFeature.layer
      }
      let layerId = layer.get('layerId')
      let layerName = layer.get('layerName')
      this.$message(`图层${layerName}开启绘制`);    
      if(layerId) {
        const vlayer = this.$refs.vlayer.find(l => {
          return l.layerId === layerId
        })
        vlayer.startDraw('LineString')
      }  
    },
    // 结束编辑
    stopEdit (layer) {
      if(!layer) {
        layer = this.activeFeature.layer
      }
      let layerId = layer.get('layerId')
      if(layerId) {
        const vlayer = this.$refs.vlayer.find(l => {
          return l.layerId === layerId
        })
        vlayer.stopDraw()
      }  
    },
    handleLineUpdated (feature) {
      console.log('handleUpdated', feature)
      this._updateLine(feature)
    },
    handleRemove (feature) {
      console.log(feature)
      this.$confirm('是否确认删除当前对象?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
           this._removeLine(feature)
        }).catch(() => {
                  
        });
    },
    _updateLine(feature) {
      const featureGeoJSON = new GeoJSON().writeFeatureObject(feature)
      updateGeo({
        table: 'line',
        geom: featureGeoJSON.geometry,
        layer_id: featureGeoJSON.properties.properties.layer_id,
        id: featureGeoJSON.properties.properties.id,
        style: featureGeoJSON.properties.properties.style,
      }).then(res  => {
        if(res.code === 0) {
           this.$message.success('更新完成')
        }
      }).finally(() => {
        // source.refresh()
      })
    },    
    _removeLine (feature) {
      const featureGeoJSON = new GeoJSON().writeFeatureObject(feature)
      let lineId = featureGeoJSON.properties.properties.id
      deleteGeo({
        table: 'line', 
        id: lineId, 
      }).then(res  => {
        if(res.code === 0) {
           this.fetchLayers()
        }
      }).finally(() => {
        // source.refresh()
      })
    },
    handleClick(evt) {
      console.log('evt.activePointers', evt.activePointers)
    },
    handleReady({map}) {
      console.log('ready', map.getLayers())

      // 选中图层

      const selected = new Style({
        fill: new Fill({
          color: '#eeeeee',
        }),
        stroke: new Stroke({
          color: 'rgba(255, 255, 255, 0.7)',
          width: 2,
        }),
      });

      function selectStyle(feature) {
        const color = feature.get('COLOR') || '#eeeeee';
        selected.getFill().setColor(color);
        return selected;
      }
      const selectClick = new Select({
        condition: click,
        style: selectStyle,
      });
      map.addInteraction(selectClick);
      selectClick.on('select', function (e) {
        console.log('select', e)
      })

    }

  }

}
</script>

<style lang="less">
body,
html {
  padding: 0;
  margin: 0;
}

.map-container {
  width: 100%;
  height: 100vh;
  text-align: left;
  .add-btn {
    padding: 20px;
    text-align: center;
  }
}
</style>